﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace Magiq.Support
{
    public class ExpressionSplit<T, TReturn>
    {
        private static readonly MethodInfo[] WhereMethods = typeof (Enumerable).GetMethods()
            .Where(x => x.Name == "Where")
            .Union(typeof (Queryable).GetMethods().Where(x => x.Name == "Where"))
            .ToArray();

        public Expression<Func<T, IEnumerable<TReturn>>> PropertyExpression { get; private set; }
        public Expression<Func<TReturn, bool>> WhereExpression { get; private set; }
        public static ExpressionSplit<T, TReturn> From(LambdaExpression lambda)
        {
            var split = new ExpressionSplit<T, TReturn>();

            var call = lambda.Body as MethodCallExpression;

            if (call != null && call.Method.GetGenericMethodDefinition().In(WhereMethods))
            {
                split.PropertyExpression = Expression.Lambda<Func<T, IEnumerable<TReturn>>>(call.Arguments[0], lambda.Parameters);
                var whereLambda = (Expression<Func<TReturn, bool>>)call.Arguments[1];
                split.WhereExpression = whereLambda;
            }
            else
            {
                split.PropertyExpression = (Expression<Func<T, IEnumerable<TReturn>>>)lambda;
            }

            return split;
        }
    }
}